iT邦幫忙

2022 iThome 鐵人賽

DAY 17
1

昨天提到,可以用Singleton模式,讓實體永遠只會建立一次。但如果現在是在多執行序的環境下,會發生什麼事呢?

  1. 第一個執行緒檢查實體是否存在。因為實體不存在,該執行緒執行建立第一個實體的程式碼部分。
  2. 然而,假設在實體化完成之前,另一個執行緒也來檢查實體成員變數是否為 null。因為第一個執行緒還什麼都沒有建立,實體成員變數仍然等於 null,所以第二個執行緒也執行了建立一個物件的程式碼。
  3. 現在,兩個執行緒都執行了 Singleton 物件的new操作,因此建立了兩個物件。

為了避免上述事情發生,我們要用 Double-Checked Locking 模式來確保程式永遠只會有一個實例。

Double-Checked Locking - 定義

用於減少加鎖開銷,尤其是為多執行緒環境中的單例模式實現「惰性初始化」。

不囉嗦上Code!

public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();

    Singleton(){}

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
								// 限制進來此處時只會有一個執行序
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}

-如果是 .Net 4 以上版本,可以用Lazy<T>來實現。

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());
    public static Singleton Instance { get { return lazy.Value; } }
    private Singleton(){}
}

簡單的小結

Double-Checked Locking模式的特點如下:

  • 在建立物件之前,增加一次檢查,避免不必要的鎖定。
  • 支援多執行緒環境。

上一篇
【DAY16】Singleton模式 - 那些年,我們一起搖的飲料(番外篇)
下一篇
【DAY18】Observer模式 - 訂閱你喜好的Youtuber!
系列文
勇闖秘境!探索物件導向背後的設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言